﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.DataModel;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	public class LayWaterValve
	{
		public LayWaterValve(Autodesk.Revit.DB.Document doc)
		{
			this.doc = doc;
			this.uiDoc = new UIDocument(doc);
		}

		public void ValvesSpecOperator(FamilyInstance fi)
		{
			List<string> pipeValvesName = new HVACUserSetting().GetPipeValvesName();
			FamilySymbol symbol = fi.Symbol;
			if (symbol == null)
			{
				return;
			}
			string familyNameBySymbol = symbol.GetFamilyNameBySymbol();
			bool flag = false;
			foreach (string value in pipeValvesName)
			{
				if (familyNameBySymbol.Equals(value))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return;
			}
			Pipe pipeByValve = this.GetPipeByValve(fi);
			if (pipeByValve == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.doc, "设置注释比例");
			try
			{
				transaction.Start();
				if (YJKRevitTools.isRiserPipe(pipeByValve))
				{
					YJKRevitTools.SetAnnotationProportation(fi, false);
				}
				else
				{
					YJKRevitTools.SetAnnotationProportation(fi, true);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private Pipe GetPipeByValve(FamilyInstance fi)
		{
			List<Connector> elementAllConnector = YJKRevitTools.GetElementAllConnector(fi);
			List<Connector> list = new List<Connector>();
			foreach (Connector connector in elementAllConnector)
			{
				if (connector.Domain == (Autodesk.Revit.DB.Domain)3)
				{
					list.Add(connector);
				}
			}
			return this.GetPipe(list);
		}

		private Pipe GetPipe(List<Connector> listConn)
		{
			if (listConn == null || listConn.Count < 1)
			{
				return null;
			}
			Pipe pipe = null;
			foreach (Connector conn in listConn)
			{
				pipe = this.GetPipeByConnector(conn);
				if (pipe != null)
				{
					break;
				}
			}
			return pipe;
		}

		private Pipe GetPipeByConnector(Connector conn)
		{
			Pipe result = null;
			Connector connectConnector = YJKRevitTools.GetConnectConnector(conn);
			if (connectConnector == null)
			{
				return result;
			}
			if (connectConnector.Owner is Pipe)
			{
				result = (connectConnector.Owner as Pipe);
				return result;
			}
			if (connectConnector.Owner is FamilyInstance)
			{
				List<Connector> elementAllConnector = YJKRevitTools.GetElementAllConnector(connectConnector.Owner as FamilyInstance);
				if (elementAllConnector == null || elementAllConnector.Count < 1)
				{
					return result;
				}
				foreach (Connector connector in elementAllConnector)
				{
					if (!connector.Origin.IsAlmostEqualTo(connectConnector.Origin, 0.0001))
					{
						Connector connectConnector2 = YJKRevitTools.GetConnectConnector(connector);
						if (connectConnector2 != null && connectConnector2.Owner is Pipe)
						{
							result = (connectConnector2.Owner as Pipe);
							return result;
						}
					}
				}
				return result;
			}
			return result;
		}

		public void Lay(FamilySymbol fs, ref string message)
		{
			if (fs == null)
			{
				return;
			}
			try
			{
				if (fs.GetFamilyNameBySymbol().Contains("自动排气阀-立管") || fs.GetFamilyNameBySymbol().Contains("末端试水阀-立管"))
				{
					for (;;)
					{
						Reference reference = this.uiDoc.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new RiserPipeFilter(), "请选择需要布置阀件的立管...");
						Pipe pipe = this.doc.GetElement(reference.ElementId) as Pipe;
						if (pipe != null)
						{
							YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
							XYZ xyz = fs.GetFamilyNameBySymbol().Contains("自动排气阀-立管") ? (-XYZ.BasisZ) : XYZ.BasisZ;
                            SearchBranch searchBranch = new SearchBranch(pipe, YArchitech.Revit.ElementType.Pipe);
							LocationCurve locationCurve = pipe.Location as LocationCurve;
							XYZ xyz2 = (locationCurve.Curve.GetEndPoint(0) + locationCurve.Curve.GetEndPoint(1)) / 2.0;
							searchBranch.DoSearch(new ElementNode(pipe, hypiping.GetNearConnectorToPoint(xyz2 + xyz)));
							ElementNode listRoot = searchBranch.GetListRoot();
							KeyValuePair<Pipe, XYZ> layRiserPipe = this.GetLayRiserPipe(listRoot, fs);
							if (layRiserPipe.Key != null)
							{
								YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(layRiserPipe.Key);
								Connector connector = fs.GetFamilyNameBySymbol().Contains("自动排气阀-立管") ? hypiping2.GetNearConnectorToPoint(layRiserPipe.Value + XYZ.BasisZ) : hypiping2.GetNearConnectorToPoint(layRiserPipe.Value - XYZ.BasisZ);
								if (connector.IsConnected)
								{
									YJKMessageBox.Information("您选择的立管端点连接器已连接！");
								}
								else
								{
									double pipeDiameter = layRiserPipe.Key.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble();
									this.LaySpeicalWaterValve(fs, connector, pipeDiameter);
								}
							}
						}
					}
				}
				else
				{
					this.uiDoc.PromptForFamilyInstancePlacement(fs);
				}
			}
			catch (Exception ex)
			{
				message = ex.Message;
				throw;
			}
		}

		private KeyValuePair<Pipe, XYZ> GetLayRiserPipe(ElementNode node, FamilySymbol fs)
		{
			Dictionary<Pipe, XYZ> source = new Dictionary<Pipe, XYZ>();
			this.GetRiserPipeAndMidpoint(node, ref source);
			if (!fs.GetFamilyNameBySymbol().Contains("自动排气阀-立管"))
			{
				return (from p in source
				orderby p.Value.Z
				select p).FirstOrDefault<KeyValuePair<Pipe, XYZ>>();
			}
			return (from p in source
			orderby p.Value.Z descending
			select p).FirstOrDefault<KeyValuePair<Pipe, XYZ>>();
		}

		private void LaySpeicalWaterValve(FamilySymbol fs, Connector conn, double pipeDiameter)
		{
			using (Transaction transaction = new Transaction(this.doc, "NewFamilyInstance"))
			{
				transaction.Start();
				fs.Activate();
				FamilyInstance familyInstance = this.doc.Create.NewFamilyInstance(conn.Origin, fs, (Autodesk.Revit.DB.Structure.StructuralType)0);
				this.doc.Regenerate();
				Parameter parameter = familyInstance.GetParameters("水管直径").FirstOrDefault<Parameter>();
				if (parameter != null && !parameter.IsReadOnly)
				{
					parameter.Set(pipeDiameter);
				}
				this.doc.Regenerate();
				if (fs.GetFamilyNameBySymbol().Contains("末端试水阀-立管"))
				{
					new YJKLine(conn.Origin, conn.Origin + familyInstance.FacingOrientation.Normalize());
					new YJKRotateFamilyInstance().RotateElem(familyInstance, conn.Origin, familyInstance.FacingOrientation.Normalize(), 180.0);
				}
				this.ConnectPipeAndFamilyInstance(conn, familyInstance, conn.Origin);
				transaction.Commit();
			}
		}

		private void GetRiserPipeAndMidpoint(ElementNode node, ref Dictionary<Pipe, XYZ> dicPipeAndMidPoint)
		{
			if (node == null)
			{
				return;
			}
			if (!(node.Element is Pipe))
			{
				this.GetRiserPipeAndMidpoint(node.Next, ref dicPipeAndMidPoint);
				return;
			}
			Pipe pipe = node.Element as Pipe;
			if (YJKRevitTools.isRiserPipe(pipe))
			{
				LocationCurve locationCurve = pipe.Location as LocationCurve;
				XYZ value = (locationCurve.Curve.GetEndPoint(0) + locationCurve.Curve.GetEndPoint(1)) / 2.0;
				dicPipeAndMidPoint.Add(pipe, value);
				this.GetRiserPipeAndMidpoint(node.Next, ref dicPipeAndMidPoint);
				return;
			}
			this.GetRiserPipeAndMidpoint(node.Next, ref dicPipeAndMidPoint);
		}

		private void ConnectPipeAndFamilyInstance(Connector riserConn, FamilyInstance fi, XYZ point)
		{
			ConnectorSetIterator connectorSetIterator = fi.MEPModel.ConnectorManager.Connectors.ForwardIterator();
			double num = double.MaxValue;
			Connector connector = null;
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector2 = obj as Connector;
				if (!connector2.IsConnected && connector2.Origin.DistanceTo(point) < num)
				{
					num = connector2.Origin.DistanceTo(point);
					connector = connector2;
				}
			}
			if (riserConn != null && connector != null)
			{
				riserConn.ConnectTo(connector);
			}
		}

		private Document doc;

		private UIDocument uiDoc;
	}
}
